﻿using System;
using System.Threading.Tasks;
using Scpi.Core.Business;
using Scpi.Core.Business.hoster;
using Scpi.Core.Command;
using Scpi.Core.Exceptions.Remote;
using Scpi.GWInstek.Command;

namespace Scpi.GWInstek.Controler
{
    public class GwPWSControler:IDisposable
    {
        private TcpClientHoster _tcpClientHost;
        public TargetInfo DeviceInfo;
        private IscpiCmd _gwPWSCommdUnit;

        private double _outputVoltage;

        public double OutputVoltage
        {
            get { return _outputVoltage; }
            set { _outputVoltage = value; }
        }

        private double _outputCurrent;

        public double OutputCurrent
        {
            get { return _outputCurrent; }
            set { _outputCurrent = value; }
        }

        private double _configVoltage;

        public double ConfigVoltage
        {
            get { return _configVoltage; }
            set { _configVoltage = value; }
        }

        private double _configCurrent;

        public double ConfigCurrent
        {
            get { return _configCurrent; }
            set { _configCurrent = value; }
        }

        private bool _isOutput;

        public bool IsOutput
        {
            get { return _isOutput; }
            set { _isOutput = value; }
        }

        public GwPWSControler(TargetInfo targetInfo)
            :this()
        {
            DeviceInfo = targetInfo;
        }

        private GwPWSControler()
        {
            _tcpClientHost = new TcpClientHoster();
            _gwPWSCommdUnit = new GwPWSCommdUnit();
        }

        public async Task<bool> ConnectRemoteAsync()
        {
            try
            {
                await _tcpClientHost.ConnectAsync(DeviceInfo.CommParam).ConfigureAwait(false);
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        /// <summary>
        /// 重新连接远端系统
        /// 最多有3次尝试连接，如果3次都失败，则会抛出RemoteConnectException异常
        /// 
        /// 异常:
        /// T:Scpi.Core.Exceptions.Remote.RemoteConnectException
        ///     3次尝试连接都失败。
        /// </summary>
        public async Task TryConnectRemote()
        {
            int tryCount = 3;

            while (tryCount>0)
            {
                if(await ConnectRemoteAsync())
                {
                    break;
                }
                else
                {
                    tryCount--;
                }
            }

            if(tryCount==0)
            {
                throw new RemoteConnectException("Connect retry 3 times,but still fails to connect");
            }
        }

        /// <summary>
        /// 设置电源的输出电压和电流
        /// </summary>
        /// <returns></returns>
        public async Task<bool> SetOutputVoltageAndCurrentAsync()
        {

            try
            {
                if (!_tcpClientHost.GetIsConnect())
                {
                    await TryConnectRemote();
                }

                await _tcpClientHost.SendData(_gwPWSCommdUnit.Apply(ConfigVoltage, ConfigCurrent));
                var recvStr= await _tcpClientHost.SendDataWitchRecvAsync(_gwPWSCommdUnit.QueryApply());

                //判断设置的是否与接收到的一致
                var results = recvStr.Split(',');
                if(results.Length==2)
                {
                    double queryVol, queryCur;

                    if(double.TryParse(results[0].Trim(), out queryVol)
                        && double.TryParse(results[1].Trim(), out queryCur))
                    {
                        if(ConfigCurrent==queryCur
                            && ConfigVoltage==queryVol)
                        {
                            return true;
                        }
                    }
                }
            }
            catch (RemoteConnectException)
            {
                //TODO
                return false;
            }
            catch(Exception)
            {
                throw;
            }

            return false;
        }
        public async Task<bool> EnablePowerOutAsync()
        {
            try
            {
                return await ControlPowerOutAsync(SwitchType.ON);
            }
            catch (Exception)
            {

                throw;
            }
        }

        public async Task<bool> DisablePowerOutAsync()
        {
            try
            {
                return await ControlPowerOutAsync(SwitchType.OFF);
            }
            catch (Exception)
            {

                throw;
            }
        }

        private async Task<bool> ControlPowerOutAsync(SwitchType switchCmd)
        {
            try
            {
                if (!_tcpClientHost.GetIsConnect())
                {
                    await TryConnectRemote();
                }

                await _tcpClientHost.SendData(_gwPWSCommdUnit.OutputCmd(switchCmd));
                var recvStr = await _tcpClientHost.SendDataWitchRecvAsync(_gwPWSCommdUnit.QueryOutputState());

                //判断设置的是否与接收到的一致
                var results = recvStr.Split(',');
                if (results.Length == 1)
                {
                    int outputState;

                    if (int.TryParse(results[0].Trim(), out outputState))
                    {
                        if (switchCmd==(SwitchType)outputState)
                        {
                            return true;
                        }
                    }
                }
            }
            catch (RemoteConnectException)
            {
                //TODO
                return false;
            }
            catch (Exception)
            {
                throw;
            }

            return false;
        }

        public void Dispose()
        {
            _tcpClientHost?.Disconnect();
        }
    }
}
